// --------------------------------------------------------------------------------------------------------------------
// <copyright file="InjectedClaimsAuthorizationManager.cs" company="AzureContrib (Open source library http://azurecontrib.codeplex.com)">
//   Microsoft Public License (Ms-PL)
// </copyright>
// <summary>
//   Simple authorization manager which delegates to the real <see cref="IAuthorizationService" />
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;

using AzureContrib.WindowsAzure.Diagnostics;
using AzureContrib.WindowsAzure.Properties;
using AzureContrib.WindowsAzure.ServiceRuntime.ServiceLocation;

using Microsoft.IdentityModel.Claims;

namespace AzureContrib.WindowsAzure.AccessControlService
{
	/// <summary>
	/// Simple authorization manager which delegates to the real <see cref="IAuthorizationService"/>
	/// </summary>
	public class InjectedClaimsAuthorizationManager : ClaimsAuthorizationManager
	{
		private static IBuilder builder;

		/// <summary>
		/// Initializes a new instance of the <see cref="InjectedClaimsAuthorizationManager"/> class. 
		/// Uses <see cref="Builder"/> to Dependency Inject this resource.
		/// </summary>
		public InjectedClaimsAuthorizationManager()
		{
			// Perhaps not the prettiest of solutions but this little module is not created through the container.
			Builder.BuildUp(this);

			Trace.Information(Strings.AuthorizationServiceInUse.F(AuthorizationService.GetType().FullName));
		}

		/// <summary>
		/// Gets or sets the <see cref="IBuilder"/>.
		/// </summary>
		/// <remarks>Please do no abuse this power!</remarks>
		/// <remarks>The purpose is to enable Dependency Injection on classes that are not createable through a factory!</remarks>
		public static IBuilder Builder
		{
			internal get
			{
				if (builder == null)
				{
					throw new Exception(Strings.BuilderIsMissing.F(typeof(InjectedClaimsAuthenticationManager)));
				}

				return builder;
			}

			set
			{
				builder = value;
			}
		}

		/// <summary>
		/// Gets or sets the <see cref="ITrace"/> to use inside of this instance.
		/// </summary>
		public ITrace Trace { get; set; }

		/// <summary>
		/// Gets or sets the <see cref="IAuthorizationService"/> which separates this module from the implementation.
		/// </summary>
		public IAuthorizationService AuthorizationService { get; set; }

		/// <summary>
		/// Forwards a call to the <see cref="IAuthorizationService.CheckAccess"/>.
		/// </summary>
		/// <param name="context">
		/// The <see cref="AuthorizationContext"/>.
		/// </param>
		/// <returns>
		/// True if access is granted.
		/// </returns>
		public override bool CheckAccess(AuthorizationContext context)
		{
			return AuthorizationService.CheckAccess(context);
		}
	}
}